<!-- 人员 计划统计 统计汇总 -->
<script setup lang="ts">
import { reactive, ref, onMounted } from "vue"
import { fetchSelectList, fetchEnumSelectList } from "@/api/common"
import { type SelectData } from "@/api/common/types/common"
import { type FormInstance } from "element-plus"
import { Search, Refresh } from "@element-plus/icons-vue"
import { userPlanStatApi } from "@/api/charts"
import { type UserReportStatSerachData, type EchartsHeatMap } from "@/api/charts/types/charts"
import * as echarts from "echarts"
import dayjs from "dayjs"

defineOptions({
  // 命名当前组件
  name: "Statistics"
})
// 今天 和后台格式 "MM-dd" 对应
const today = (): string => {
  return dayjs().format("MM-DD")
}
const getDateRange = () => {
  // 获取选中的日期
  const selectedDate = dayjs(new Date())
  // 计算当前选择日期所在月的第一天和最后一天
  const startOfMonth = selectedDate.startOf("month") // 获取该月的1号
  const endOfMonth = selectedDate.endOf("month") // 获取该月的最后一天
  // 设置开始日期和结束日期
  const startDate = startOfMonth.format("YYYY-MM-DD")
  const endDate = endOfMonth.format("YYYY-MM-DD")
  return { startDate, endDate }
}

const { startDate, endDate } = getDateRange()

const loading = ref<boolean>(false)
const searchFormRef = ref<FormInstance | null>(null)
// 查询参数
const searchData = reactive<UserReportStatSerachData>({
  startDate: startDate,
  endDate: endDate,
  groupIds: [],
  projectIds: [],
  projectType: undefined,
  whole: true // 是否统计全部, 否则只统计有计划的人员
})

//project 类型下拉框
const projectTypeOptions = ref<SelectData[]>([])
const fetchProjectTypeOptions = async () => {
  const data = await fetchEnumSelectList("ProjectType")
  projectTypeOptions.value = data.data
}

// 项目下拉框
const projectSelectOptions = ref<SelectData[]>([])
const fetchProjectSelectOptions = async () => {
  const data = await fetchSelectList("project")
  projectSelectOptions.value = data.data
}

// 小组下拉框
const groupSelectOptions = ref<SelectData[]>([])
const fetchGroupSelectOptions = async () => {
  const data = await fetchSelectList("group")
  groupSelectOptions.value = data.data
}

const handleSearch = () => {
  searchFormRef.value?.validate((valid: boolean, fields) => {
    if (!valid) return console.error("表单校验不通过", fields)

    loading.value = true
    userPlanStatApi(searchData)
      .then(({ data }) => {
        planStatData.value = data
        weekStatChartsInit()
      })
      .catch(() => {
        console.log("getStatWeek error")
        planStatData.value = null
      })
      .finally(() => {
        loading.value = false
      })
  })
}
// 计划统计数据
const planStatData = ref<EchartsHeatMap | null>(null)

const planStatRef = ref(null)
const resetSearch = () => {
  searchFormRef.value?.resetFields()
  handleSearch()
}

const weekStatChartsInit = () => {
  if (!planStatData.value) return

  const planStatDom = planStatRef.value

  if (!planStatDom) return

  let planStatChart = echarts.getInstanceByDom(planStatDom)

  if (!planStatChart) {
    planStatChart = echarts.init(planStatDom) // **只有在没有实例时才初始化**
  }

  // 热力图
  const { xAxisData, yAxisData, heatmapData, dataDetails } = planStatData.value

  const todayIndex = xAxisData.indexOf(today()) // 找到今日在 x 轴的索引

  const transformedData = heatmapData.map(([xIndex, yIndex, value]) => ({
    value: [xIndex, yIndex, value || "-"],
    detail: dataDetails[`${xIndex}_${yIndex}`] || "无详情"
  }))

  const option: echarts.EChartsOption = {
    tooltip: {
      position: "bottom",
      renderMode: "html", // 允许 HTML 渲染
      formatter: (params: any) => {
        const [xIndex, yIndex, value] = params.value
        const detail = params.data.detail
        return `<strong>日期</strong>: ${xAxisData[xIndex]}  <strong>姓名</strong>:: ${yAxisData[yIndex]}  <strong>工时</strong>: ${value}<br/>
                <br/>${detail}`
      }
    },
    grid: {
      height: "70%",
      top: "5%",
      bottom: "10%"
    },

    xAxis: {
      type: "category",
      data: xAxisData,
      splitArea: {
        show: true
      },
      axisLabel: {
        interval: 0, // **强制所有标签都显示**
        rotate: -45 //代表逆时针旋转45度
      }
    },
    yAxis: {
      type: "category",
      data: yAxisData,
      splitArea: {
        show: true
      },
      axisLabel: {
        interval: 0 // **强制所有标签都显示**
      }
    },
    visualMap: {
      min: 0,
      max: 10,
      calculable: true,
      orient: "horizontal",
      left: "center",
      bottom: "5%" // 10 -> 5
    },
    series: [
      {
        name: "Heat Map",
        type: "heatmap",
        data: transformedData,
        label: {
          show: true,
          formatter: (params: any) => params.data.value[2] // 显示工时数值 CPLEASE-3492
        },

        emphasis: {
          itemStyle: {
            shadowBlur: 10,
            shadowColor: "rgba(0, 0, 0, 0.3)" // hover时增强阴影
          }
        },

        // 正确的分割线配置（无报错+位置正确）
        markLine: {
          silent: true, // 关闭交互
          symbol: "none", // 无箭头
          lineStyle: {
            color: "#ff4d4f", // 红色点线
            width: 1.5,
            type: "dotted", // 虚线点样式
            opacity: 0.7 // 半透明
          },
          label: {
            show: true,
            formatter: " 日报<--_-->计划",
            color: "#ff4d4f"
          },
          // 仅保留线，不配置任何标签
          data:
            todayIndex !== -1
              ? [
                  {
                    xAxis: todayIndex // 线穿过今日单元格中间
                  }
                ]
              : []
        }
      }
    ]
  }
  planStatChart.setOption(option)
}

onMounted(() => {
  fetchProjectSelectOptions()
  fetchGroupSelectOptions()
  fetchProjectTypeOptions()
  handleSearch()
})
</script>

<template>
  <div class="app-container">
    <el-card v-loading="loading" shadow="never" class="search-wrapper">
      <el-form ref="searchFormRef" :inline="true" :model="searchData" size="small">
        <el-form-item prop="startDate" label="开始日期" :rules="[{ required: true, message: '开始日期必填' }]">
          <el-date-picker
            v-model="searchData.startDate"
            type="date"
            style="width: 120px"
            value-format="YYYY-MM-DD"
            date="开始日期"
          />
        </el-form-item>

        <el-form-item prop="endDate" label="结束日期" :rules="[{ required: true, message: '结束日期必填' }]">
          <el-date-picker
            v-model="searchData.endDate"
            type="date"
            style="width: 120px"
            value-format="YYYY-MM-DD"
            date="结束日期"
          />
        </el-form-item>

        <el-form-item prop="projectType" label="项目类型">
          <el-select
            v-model="searchData.projectType"
            clearable
            filterable
            placeholder="请选择项目类型"
            style="width: 120px"
            :empty-values="[null]"
          >
            <el-option v-for="item in projectTypeOptions" :key="item.id" :label="item.text" :value="item.id" />
          </el-select>
        </el-form-item>

        <el-form-item prop="projectIds" label="所属项目">
          <el-select
            v-model="searchData.projectIds"
            clearable
            multiple
            filterable
            placeholder="请选择项目"
            style="width: 180px"
            :empty-values="[null]"
          >
            <el-option v-for="item in projectSelectOptions" :key="item.id" :label="item.text" :value="item.id" />
          </el-select>
        </el-form-item>

        <el-form-item prop="groupIds" label="小组">
          <el-select
            v-model="searchData.groupIds"
            clearable
            multiple
            placeholder="请选择小组"
            style="width: 200px"
            :empty-values="[null]"
          >
            <el-option v-for="item in groupSelectOptions" :key="item.id" :label="item.text" :value="item.id" />
          </el-select>
        </el-form-item>

        <el-form-item prop="whole" label="">
          <el-switch
            v-model="searchData.whole"
            inline-prompt
            @change="handleSearch"
            active-text="全部人员"
            inactive-text="计划投入人员"
            :active-value="true"
            :inactive-value="false"
            style="--el-switch-on-color: #13ce66; --el-switch-off-color: #409eff"
          />
        </el-form-item>

        <el-form-item>
          <el-button type="primary" :icon="Search" @click="handleSearch">查询</el-button>
          <el-button :icon="Refresh" @click="resetSearch">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>
    <el-card v-loading="loading" shadow="hover">
      <div class="">
        <div>
          <el-alert title="今天之前:统计的是日报工时，今天以及之后:统计的是计划工时" type="success" />
        </div>
      </div>

      <div class="table-wrapper">
        <div style="width: 100%; min-height: 800px" ref="planStatRef" />
      </div>
    </el-card>
  </div>
</template>

<style lang="scss" scoped>
.search-wrapper {
  margin-bottom: 20px;

  :deep(.el-card__body) {
    padding-bottom: 2px;
  }
}

.toolbar-wrapper {
  display: flex;
  justify-content: space-between;
  margin-bottom: 20px;
}

.table-wrapper {
  margin-bottom: 20px;
}
</style>
